package yxxy.c_020;

import java.util.concurrent.locks.ReentrantLock;

/**
 * reentrantLock：可重入锁
 * reentrantLock用于代替synchronized
 * 本例中由于m1锁定this，只有在m1执行完成后，m2才可执行。
 * 这里主要用于复习synchronized
 * <p>
 * <p>
 * 使用reentrantLock可以完成同样的功能
 * 需求注意的是，必须要必须要必须要手动释放锁(重要的事情说三遍)
 * 使用synchronized锁定的话如果遇到异常，jvm会自动释放锁。但是lock必须手动释放锁，因此经常在finally中进行锁的释放
 * <p>
 * <p>
 * 使用reentrantLock可以进行"尝试锁定"tryLock，这样无法锁定，或者在指定时间内无法锁定，线程可以决定是否继续等待
 * <p>
 * <p>
 * 使用reentrantLock还可以调用lockInterruptibly方法，可以对线程interrupt方法做出响应，
 * 在一个线程等待锁的过程中，可以被打断
 * <p>
 * <p>
 * reentrantLock还可以指定为公平锁，公平锁：谁待的时间最长则谁就可以获取得，类似于负载均衡。
 *
 * @create: 2019-08-26 21:32
 **/
public class ReentrantLock5 extends Thread {

    //参数为true表示为公平锁
    private static ReentrantLock lock = new ReentrantLock(true);

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            try {
                lock.lock();
                System.out.println(Thread.currentThread().getName() + "获取了锁");
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } finally {
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) {
        ReentrantLock5 r5 = new ReentrantLock5();

        Thread t1 = new Thread(r5, "线程1");
        Thread t2 = new Thread(r5, "线程2");

        t1.start();
        t2.start();
    }
}
